package com.hrbxlh.virtualization.listener;

import com.hrbxlh.virtualization.dao.ContainerMapper;
import com.hrbxlh.virtualization.enums.ContainerStatusEnum;
import com.hrbxlh.virtualization.pojo.Container;
import com.hrbxlh.virtualization.pojo.ContainerExample;
import com.hrbxlh.virtualization.service.DockerService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.DelayQueue;

/**
 * 定时停止容器
 *
 * @author cheer
 */
@Component
public class ContainerStopListener implements ApplicationListener<ContextRefreshedEvent> {

    private Logger logger = LoggerFactory.getLogger(ContainerStopListener.class);

    private static DelayQueue<ContainerStopDelayTask> delayQueue = new DelayQueue<>();

    @Autowired
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    @Autowired
    private ContainerMapper containerMapper;

    @Autowired
    private DockerService dockerService;

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        if (event.getApplicationContext().getParent() == null) {
            // 服务器启动后捞取数据库中运行状态的容器，对其进行停止操作
            ContainerExample containerExample = new ContainerExample();
            containerExample.or().andContainerStatusEqualTo(ContainerStatusEnum.RUNNING.getCode());
            List<Container> containerList = containerMapper.selectByExample(containerExample);
            containerList.forEach(container -> threadPoolTaskExecutor.execute(() -> {
                dockerService.stopContainer(container.getRancherId());
                container.setContainerStatus(ContainerStatusEnum.STOPPED.getCode());
                containerMapper.updateByPrimaryKeySelective(container);
            }));

            new Thread(() -> {
                logger.info("定时停止容器子程序开启");
                while (true) {
                    try {
                        ContainerStopDelayTask containerStopDelayTask = delayQueue.take();
                        threadPoolTaskExecutor.execute(containerStopDelayTask);
                    } catch (Exception e) {
                        logger.error(e.getMessage(), e);
                    }
                }
            }).start();
        }
    }

    public static DelayQueue<ContainerStopDelayTask> getDelayQueue() {
        return delayQueue;
    }
}
